package org.jugile.util;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import org.jugile.util.Jugile;
import org.jugile.util.Node;

/*

Copyright (C) 2007-2014 Jukka Rahkonen  email: jukka.rahkonen@iki.fi

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*/

/**
 * "All things were made by him; and without him was not any thing made that was made.
 *  In him was life; and the life was the light of men. And the light shineth in darkness; 
 *  and the darkness comprehended it not." (John 1:3-5)
 * 
 * ===========
 * 
 * Very simple Rest client. Why it should be any more complicated than this 100 lines of java?
 * @author jukka.rahkonen@iki.fi
 */
public class Rest extends Jugile {

	private String url;
	public Rest(String url) {
		this.url = url;
	}

	private Map<String,String> params = new HashMap<String,String>();
	
	public String get(String path) { return rest("GET",path,null,null); }
	public String getJson(String path) { return rest("GET",path,null,"json"); }
	public String post(String path, String data) { return rest("POST",path,data,null); }
	public String postJson(String path, String data) { return rest("POST",path,data,"json"); }
	public String put(String path, String data) { return rest("PUT",path,data,null); }
	public String putJson(String path, String data) { return rest("PUT",path,data,"json"); }
	public String post(String path) { return rest("POST",path,null,null); }
	public String postJson(String path) { return rest("POST",path,null,"json"); }
	public String delete(String path) { return rest("DELETE",path,null,null); }
	public String deleteJson(String path) { return rest("DELETE",path,null,"json"); }
	public void param(String name, String value) { params.put(name,value); }
	
	public String rest(String method, String path, String data, String format) {
		BufferedReader in = null;
		OutputStreamWriter out = null;
		try {
			if ("GET".equals(method) && params.size() > 0) {
				StringBuffer query = new StringBuffer("?");
				for (String key : params.keySet()) {
					query.append(key);
					query.append("=");
					query.append(URLEncoder.encode(params.get(key),"UTF-8"));
					query.append("&");
				}
				path = path + query.toString();
				params = new HashMap<String,String>();
			}
			URL u = new URL(url+path);
			HttpURLConnection uc = (HttpURLConnection)u.openConnection();
			uc.setRequestProperty("Accept", "application/xml");
			if (eq("json",format)) uc.setRequestProperty("Accept","application/json");
			uc.setRequestMethod(method);
			if ("POST".equals(method) && params.size() > 0) {
				uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
				uc.setDoOutput(true);
				//uc.setDoInput(true);
				out = new OutputStreamWriter(uc.getOutputStream(),"UTF-8");
				for (String key : params.keySet()) {
					out.write(key);
					out.write("=");
					out.write(URLEncoder.encode(params.get(key), "UTF-8"));
					out.write("&");
				}
				out.close(); out = null;
				params = new HashMap<String,String>();
			} else if ("PUT".equals(method) || ("POST".equals(method) && params.size() == 0)) {
	            uc.setRequestProperty("Content-Type", "application/xml");
	            if (eq("json",format)) uc.setRequestProperty("Content-Type","application/json");
				uc.setDoOutput(true);
				out = new OutputStreamWriter(uc.getOutputStream());
				//if ("POST".equals(method)) data = URLEncoder.encode(data,"UTF-8");
				out.write(data);
				out.close(); out = null;
			}
			
			if (uc.getResponseCode() != 200) {
				fail("STATUS:" + uc.getResponseCode() + " " + uc.getResponseMessage());
			}

            //get result
            in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
			StringBuilder response = new StringBuilder();
			String inputLine;
			while ((inputLine = in.readLine()) != null) 
				response.append(inputLine + "\n");
			in.close(); in = null;
			return response.toString();
		} catch (Exception e) { 
			fail(e); 
		} finally {
			if (in != null) try { in.close(); } catch(Exception e) { }
			if (out != null) try { out.close(); } catch(Exception e) { }
		}
		return null;		
	}
	
	
}
